package cn.demo.d01;

import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;

public class Demo03 {
    public static void main(String[] args) {
        // test16();
        // System.out.println("--------------------");
        // test17();
        // System.out.println("--------------------");
        // test18();
        // System.out.println("--------------------");
        // test19();
        // System.out.println("--------------------");
        // test20();
        // System.out.println("--------------------");
        // test21();
        // System.out.println("--------------------");
        // test22();
        // System.out.println("--------------------");
        // test23();
        // System.out.println("--------------------");
        // test24();
        // System.out.println("--------------------");
        // test25();
        // test26();
        // System.out.println("--------------------");
        // test27();
        // test28();
        // System.out.println("--------------------");
        test29();
        test30();
        System.out.println("--------------------");
    }

    /**
     //定义数组求最大值：33,5,22,44,55

     //扩展问题：
     //1.根据求最大值的思路，自己改写一下求最小智
     //2.为什么max要记录为arr[0],默认值不能为0吗？
     //不能写0
     //max的初始化值一定要是数组中的值。
     //3.循环中开始条件一定是0吗？
     //循环的开始条件如果为0，那么第一次循环的时候是自己跟自己比了一下，对结果没有任何影响，但是效率偏低
     //为了提高效率，减少一次循环的次数，循环开始条件可以写1.
     * */
    private static void test16() {
        System.out.println("请输入5个数,取最大值");
        Scanner scanner = new Scanner(System.in);
        int[] arr = new int[5];
        for (int i = 0; i < 5; i++) {
            arr[i] = scanner.nextInt();
        }
        int max = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] > max){
                max = arr[i];
            }
        }
        System.out.println("最大值是：" + max);
    }

    /**
     需求：生成10个95~105之间的随机数存入数组。
     1）求出所有数据的和
     2）求所有数据的平均数
     3）统计有多少个数据比平均值小
     * */
    private static void test17(){
        System.out.println("请输入随机数范围");
        Scanner scanner = new Scanner(System.in);
        System.out.println("开始");
        int begin = scanner.nextInt();
        System.out.println("结束");
        int end = scanner.nextInt();
        Random r = new Random();
        int[] arr = new int[10];
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            arr[i] = r.nextInt(end-begin+1) + begin;
            System.out.println(arr[i]);
            sum += arr[i];
        }
        double avg = (double) sum/arr.length;
        int count = 0;
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] < avg) {
                count++;
            }
        }
        System.out.println("1）求出所有数据的和: " + sum);
        System.out.println("2）求所有数据的平均数: " + avg);
        System.out.println("3）统计有多少个数据比平均值小: " + count);
    }

    /**
     需求：定义一个数组，存入1,2,3,4,5。交换首尾索引对应的元素。
     交换前：1,2,3,4,5
     交换后：5,4,3,2,1
     * */
    private static void test18(){
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入你要保存的数量");
        int count =  scanner.nextInt();
        int[] arr = new int[count];
        System.out.println("存入"+(arr.length)+"个数");
        for (int i = 0; i < arr.length; i++) {
            arr[i] = scanner.nextInt();
        }
        for (int i = 0,j=arr.length-1; i < j; i++,j--) {
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
        System.out.println();
    }

    /**
     * 需求：定义一个数组，存入1~5。要求打乱数组中所有数据的顺序。
     * 难点：如何获取数组中的随机索引
     */
    private static void test19(){
        int[] arr = {1,2,3,4,5};
        Random random = new Random();
        for (int i = 0; i < arr.length; i++) {
            int index = random.nextInt(arr.length);
            int temp = arr[i];
            arr[i] = arr[index];
            arr[index] = temp;
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
        System.out.println();
    }

    /*朋友聚会的时候可能会玩一个游戏：逢7过
        游戏规则：从任意一个数字开始报数，当你要报的数字是包含7或者是7的倍数时都要说过：过
        需求：使用程序在控制台打印出1-100之间的满足逢七必过规则的数据*/
    private static void test20(){
        for (int i = 1; i <= 100; i++) {
            if (i==7 || i%7==0 || i%10==7 || i/10%10==7){
                System.out.println("过 ");
            }else{
                System.out.println(i+" ");
            }
        }
    }

    /*需求：键盘录入一个大于等于2的整数 x ，计算并返回 x 的 平方根 。
        结果只保留整数部分 ，小数部分将被舍去 。*/
    private static void test21(){
        //分析：
        //平方根   16的平方根4
        //         4的平方根2


        // 10
        // 1 * 1 = 1 < 10
        // 2 * 2 = 4 < 10
        // 3 * 3 = 9 < 10
        // 4 * 4 = 16 > 10
        //推断：10的平方根是在3~4之间。


        // 20
        // 1 * 1 = 1 < 20
        // 2 * 2 = 4 < 20
        // 3 * 3 = 9 < 20
        // 4 * 4 = 16 < 20
        // 5 * 5 = 25 > 20
        //推断：20的平方根是在4~5之间。


        //在代码当中
        //从1开始循环，拿着数字的平方跟原来的数字进行比较
        //如果小于的，那么继续往后判断
        //如果相等，那么当前数字就是平方根
        //如果大于的，那么前一个数字就是平方跟的整数部分


        //1.键盘录入一个整数
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个整数");
        int number = sc.nextInt();
        //2.从1开始循环判断
        //开始：1 结束: number
        for (int i = 1; i <= number; i++) {
            int temp = i*i;
            if (temp == number){
                System.out.println(number+" 的平方根是："+i);
                //一旦找到了，循环就可以停止了，后面的数字就不需要再找了，提高代码的运行效率。
                break;
            }else if(temp > number){
                System.out.println(number+" 的平方根的整数部分是："+(i-1));
                break;
            }
        }
    }

    //需求：键盘录入一个正整数 x ，判断该整数是否为一个质数。

    //质数：
    //如果一个整数只能被1和本身整除，那么这个数就是质数。否则这个数叫做合数
    //7 = 1 * 7 质数
    //8 = 1 * 8  2 * 4 合数
    private static void test22(){
        //分析：
        //1.键盘录入一个正整数
        //number
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个正整数");
        int number = sc.nextInt();//9
        //定义一个变量，表示标记
        //标记着number是否为一个质数
        //true： 是一个质数
        //false : 不是一个质数

        //表示最初就认为number是一个质数
        boolean flag = true;

        //2.判断
        //写一个循环，从2开始判断，一直判断到number-1为止
        //看这个范围之内，有没有数字可以被number整除
        int i = 2;
        for (; i < (int)Math.sqrt(number); i++){
            //i 依次表示这个范围之内的每一个数字
            //看number是否能被i整除就可以了
            if (number % i == 0){
                flag = false;
                break;
            }
        }
        System.out.println("i: "+i+" num:"+number+" newNum:"+(int)Math.sqrt(number));
        //只有当这个循环结束了，表示这个范围之内所有的数字都判断完毕了
        //此时才能断定number是一个质数
        if(flag){
            System.out.println(number + "是一个质数");
        }else{
            System.out.println(number + "不是一个质数");
        }
    }

    //需求：
    //随机数范围：1~100
    private static void test23(){
        //创建对象
        Random r = new Random();
        //生成随机数
        int number = r.nextInt(100) + 1;//1  ~ 100
        System.out.println(number);


        //秘诀
        //用来生成任意数到任意数之间的随机数 7 ~15
        //1.让这个范围头尾都减去一个值，让这个范围从0开始  -7   0~8
        //2.尾巴+1       8 + 1 = 9
        //3.最终的结果，再加上第一步减去的值。

       /* Random r = new Random();
        int number = r.nextInt(9) + 7;// 7 ~ 15
                //   0 ~ 8  + 7
        System.out.println(number);*/
    }

    //需求：程序自动生成一个1-100之间的随机数字，使用程序实现猜出这个数字是多少？
    //扩展小需求：加一个保底机制，3次猜不中，直接提示猜中了。
    private static void test24(){
        Random r = new Random();
        int randNum = r.nextInt(100)+1;
        System.out.println("保底几次："+randNum);
        Scanner sc = new Scanner(System.in);
        int num = sc.nextInt();
        for (int i = 0; i < num; i++) {
            System.out.println("请输入:");
            int curNum = sc.nextInt();
            if (curNum == randNum){
                System.out.println("恭喜你猜对了: " + curNum);
                break;
            }
            if (i == (num-1)){
                System.out.println("恭喜你保底猜对了: " + curNum+", 实际: "+i);
                break;
            }
            if (curNum > randNum){
                System.out.println("大了,再来了: " + i);
            }else{
                System.out.println("小了,再来了: " + i);
            }

       }
    }

    /**
     现有一个整数数组，数组中的每个元素都是[0-9]之间的数字，从数组的最大索引位置开始到最小索引位置，
     依次表示整数的个位、十位、百位。。。依次类推。请编写程序计算，这个数组所表示的整数值。例如：
     数组：{2, 1, 3, 5, 4}
     表示的整数为：21354 // 注：是整数类型的两万一千三百五十四，不是字符串拼起来的。
     * */
    private static void test25(){
        //1.定义数组
        int[] arr = {1, 3, 5, 7, 9};
        //2.定义变量存储最终的整数
        int num = 0;
        //3.对数组进行遍历
        for (int i = 0; i < arr.length; i++) {
            //4.计算，高位乘以10再加上当前位的值
            num = num * 10 + arr[i];
        }
        //5.打印结果
        System.out.println(num);
    }

    private static void test26(){
        //1.定义数组
        int[] arr = {1, 3, 5, 7, 9};
        //2.定义变量存储最终的整数
        int num = 0;
        //3.对数组进行遍历
        for (int i = arr.length-1; i >=0 ; i--) {
            num = num*10+arr[i];
        }
        System.out.println(num);
    }

    /**
     有一个数组，其中有十个元素从小到大依次排列 {12,14,23,45,66,68,70,77,90,91}。
     再通过键盘录入一个整数数字。要求：把数字放入数组序列中，生成一个新的数组，并且数组的元素依旧是从小到大排列的。执行效果如下：
     * */
    private static void test27(){
        int[] arr = {12,14,23,45,66,68,70,77,90,91};
        int[] newArr = new int[arr.length+1];
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个整数数字：");
        int num = scanner.nextInt();
        int index = 0;
        for (int i = 0; i < arr.length; i++) {
            if(arr[i]<num){
                newArr[i] = arr[i];
                index = i+1;
            }else{
                newArr[i+1] = arr[i];
            }
        }
        newArr[index] = num;
        for (int i = 0; i < newArr.length; i++) {
            System.out.print(newArr[i]+" ");
        }
    }

    public static void test28() {
        //1.定义长度为10的原数组
        int[] arr = {12,14,23,45,66,68,70,77,90,91};
        //2.定义长度为11的空数组
        int[] brr = new int[11];
        //3.键盘录入数组
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个整数数字");
        int num = sc.nextInt();
        //4.定义变量代表要插入的位置
        int index = 0;
        //5.循环遍历原数组
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] <= num) {
                //5.1如果元素小于等于要插入的数字，则直接存放
                brr[i] = arr[i];
                //5.2把i后面的位置记录下来
                index = i + 1;
            }else{
                //5.3如果元素大于要插入的数字,则往后一个位置存放
                brr[i+1] = arr[i];
            }
        }
        //6.index存储的就是要插入的位置
        brr[index] = num;
        //7.遍历新数组查看结果
        System.out.print("生成的新数组是：");
        for (int i = 0; i < brr.length; i++) {
            System.out.print(brr[i] + " ");
        }
    }

    /*
    定义一个数组其中包含多个数字。用自己的方式最终实现，奇数放在数组的左边，偶数放在数组的右边。（可以创建其他数组，不必须在原数组中改变）
    1. 定义一个新数组。把原数组的奇数放在新数组的左边，把原数组的偶数放在新数组的右边。
    2. 不定义新数组。找到左边的偶数，和右边的奇数互换位置。
    * */
    private static void test29(){
        int[] arr = {12,23,34,45,56,67,78,89,90};
        int[] newArr = new int[arr.length];
        int left = 0;
        int right = arr.length - 1;
        for (int i = 0; i < arr.length; i++) {
            if (arr[i]%2==0){
                newArr[right] = arr[i];
                right--;
            }else{
                newArr[left] = arr[i];
                left++;
            }
        }
        System.out.println("旧数组是：" + Arrays.toString(arr));
        System.out.println("新数组是：" + Arrays.toString(newArr));
    }

    private static void test30(){
        int[] arr = {12,23,34,45,56,67,78,89,90};
        int left = 0;
        int right = arr.length - 1;
        int count = 0;
        while (left < right){
            count++;
            if (arr[left]%2==1){
                left++;
            }else if(arr[right]%2==0){
                right--;
            }else{
                int temp = arr[left];
                arr[left] = arr[right];
                arr[right] = temp;
                left++;
                right--;
            }
        }
        for (int i : arr) {
            System.out.print(i+" ");
        }
        System.out.println();
        System.out.println("共交换了"+count+"次");
    }
}
